package ca.uwaterloo.jfeldste;

import ca.swank.hardquor.*;

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.ComponentEvent.*;

public class hqGUI implements hardquorUserGame {
    private static String backgroundFile = "resources/jfeldste/background.jpg";
    private static String backgroundFile2 = "resources/jfeldste/background2.jpg";
    private static String spaceFile = "resources/jfeldste/space.jpg";
    private static String spaceFile2 = "resources/jfeldste/space2.jpg";
    private static String piece1File = "resources/jfeldste/piece1.gif";
    private static String piece2File = "resources/jfeldste/piece3.gif";
    private static String wall1File = "resources/jfeldste/wall1.jpg";
    private static String wall2File = "resources/jfeldste/wall2.jpg";

	private static hardquorGameClient game;
	private static TextArea ta;
	private static JTextField tf;
	private static hqImagePanel imagePanel;
	private static int playerNum;
	private static JFrame frame;


  public hqGUI(hardquorGameClient game, int playerNum)
  { this.game = game;
  	this.playerNum = playerNum;
    display();
  }

  /*public static void main(String[] args)
  { display();
  }
*/
    public static void display() {
		// Set images
        Image background = Toolkit.getDefaultToolkit().getImage(hqGUI.backgroundFile);
        Image background2 = Toolkit.getDefaultToolkit().getImage(hqGUI.backgroundFile2);
        Image space = Toolkit.getDefaultToolkit().getImage(hqGUI.spaceFile);
        Image space2 = Toolkit.getDefaultToolkit().getImage(hqGUI.spaceFile2);
        Image piece1 = Toolkit.getDefaultToolkit().getImage(hqGUI.piece1File);
        Image piece2 = Toolkit.getDefaultToolkit().getImage(hqGUI.piece2File);
        Image wall1 = Toolkit.getDefaultToolkit().getImage(hqGUI.wall1File);
        Image wall2 = Toolkit.getDefaultToolkit().getImage(hqGUI.wall2File);

		ta = new TextArea(20,10);
		tf = new JTextField("");

        // Make panel for images
        imagePanel = new hqImagePanel(background, space, space2, piece1, piece2, wall1, wall2, tf, game, playerNum);

		imagePanel.setBorder(BorderFactory.createCompoundBorder(
			          BorderFactory.createTitledBorder("Hardquor"),
                      BorderFactory.createEmptyBorder(2,325,727,325)));

        // Make panel for combo box
        JPanel optionsPanel = new JPanel();

		// Get .hqSkin files

		/*String[] imageFiles = list(new FilenameFilter() {
			public boolean accept(File d, String name) { return name.endsWith(".hqSkin");}
		});

		for(int i=0;i<imageFiles.length;i++) {
			System.out.println(imageFiles[i]);
		}
*/
		// Create combo box with Skin choices
		/*String[] skins = { "New", "Waxing Crescent", "First Quarter",
				            "Waxing Gibbous", "Full", "Waning Gibbous",
				            "Third Quarter", "Waning Crescent" };
		JComboBox skinChoices = new JComboBox(skins);
		*/
		JButton skinButton = new JButton("Skin");
		JLabel fileLabel = new JLabel(" Default");

		//skinChoices.setSelectedIndex(0);
		//optionsPanel.add(skinChoices);


		JPanel messagePanel = new JPanel();
		messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS));
		messagePanel.add(tf);
		tf.setMinimumSize(new Dimension(240, 30));
		tf.setPreferredSize(new Dimension(240, 30));
		tf.setMaximumSize(new Dimension(240, 30));
		messagePanel.add(Box.createRigidArea(new Dimension(0,8)));
		messagePanel.add(ta);
		messagePanel.setOpaque(false);
		//messagePanel.add(Box.createVerticalGlue());
		messagePanel.setBorder(BorderFactory.createCompoundBorder(
		              BorderFactory.createTitledBorder("Messages"),
                      BorderFactory.createEmptyBorder(2,2,2,2)));

//		optionsPanel.setLayout(new GridLayout(0,2));
		optionsPanel.add(skinButton);
		skinButton.setMinimumSize(new Dimension(70, 25));
		skinButton.setPreferredSize(new Dimension(70, 25));
		skinButton.setMaximumSize(new Dimension(70, 25));
		optionsPanel.add(fileLabel);
		optionsPanel.setOpaque(false);
		optionsPanel.setBorder(BorderFactory.createCompoundBorder(
                      BorderFactory.createTitledBorder("Options Menu"),
                      BorderFactory.createEmptyBorder(2,2,2,2)));

        hqSidePanel sidePanel = new hqSidePanel(background2);
        sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.Y_AXIS));
        sidePanel.add(optionsPanel);
        sidePanel.add(messagePanel);
        //sidePanel.add(Box.createVerticalGlue());
        sidePanel.setBorder(BorderFactory.createCompoundBorder(
		              BorderFactory.createTitledBorder("Hardquor Menu"),
		              BorderFactory.createEmptyBorder(2,2,2,2)));



//2, 30, 710, 30
		// Main Panel
		JPanel mainPanel  = new JPanel();
		mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));
		mainPanel.add(imagePanel);
		mainPanel.add(sidePanel);
		// Adjusts the layout
		/*
		GridBagLayout gridbag = new GridBagLayout();
		mainPanel.setLayout(gridbag);
		GridBagConstraints c = new GridBagConstraints();

		c.gridx = 0;
		c.gridy = 0;
		gridbag.setConstraints(imagePanel, c);
		mainPanel.add(imagePanel);

		c.gridx = 1;
		c.gridy = 0;
		gridbag.setConstraints(optionsPanel, c);
	    mainPanel.add(sidePanel);
*/
	    /*c.gridx = 1;
		c.gridy = 1;
		gridbag.setConstraints(optionsPanel, c);
	    mainPanel.add(messagePanel);
*/
		/*// Add the select and display panels to the main panel.
		mainPanel.add(imagePanel);
		mainPanel.add(comboPanel);
*/
		// Make JFrame
        frame = new JFrame("Hardquor");

        // Set WindowListener for window closing
        frame.addWindowListener(new hqSimpleGUICloseHandler(game));

		// Set frame properties
        frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
        frame.setSize(new Dimension(950, 790));
        frame.setVisible(true);

		skinButton.addActionListener(new FileOpenListener(frame, imagePanel, fileLabel));
	}

  public void notifyError(int errorCode)
  { System.out.println("notifyError(" + errorCode + ")");
  }

  public void notifyMove(int[] source, int[] target)
  { System.out.println("notifyMove(" + source[0] + "," + source[1] + " " + target[0] + "," + target[1] + ")");
	//Current player walks
	if (imagePanel.p1x == source[0] && imagePanel.p1y == source[1]) {
		imagePanel.p1x = target[0];
		imagePanel.p1y = target[1];
	}
	else if (imagePanel.p2x == source[0] && imagePanel.p2y == source[1]) {
		imagePanel.p2x = target[0];
		imagePanel.p2y = target[1];
	}
	else {
		System.out.println("WALK ERROR!");
	}
	imagePanel.repaint();
  }

  public void notifyMove(int[] a1, int[] a2, int[] b1, int[] b2)
  { System.out.println("notifyMove(" + a1[0] + "," + a1[1] + " " + a2[0] + "," + a2[1] + " " + b1[0] + "," + b1[1] + " " + b2[0] + "," + b2[1] + ")");
  	if(a1[0] == a2[0])
  		imagePanel.walls[a1[0]][a1[1]].setBottom();
  	else if(a1[0] == b1[0])
		imagePanel.walls[a1[0]][a1[1]].setRight();
	else {
		System.out.println("WALL ERROR!");
	}
	imagePanel.repaint();
  }

  public void notifyQuit(java.lang.String user)
  { System.out.println("notifyQuit(" + user + ")");
  	frame.setVisible(false);
  }

  public void notifySpeak(java.lang.String user, java.lang.String message)
  { System.out.println("notifySpeak(" + user + ":" + message + ")");
  	ta.setText(ta.getText() + "\n" + user + ": " + message);
  }

  public void notifyTurn()
  { System.out.println("notifyTurn()");
  }

  public void notifyWinner(java.lang.String winnerName)
  { System.out.println("notifyQuit(" + winnerName + ")");
  }

}

class hqSidePanel extends JPanel {
	public Image background;

	public hqSidePanel(Image background) {
		this.background = background;
	}
	public void paintComponent(Graphics g) {
		//paint background
        super.paintComponent(g);
        g.drawImage(background, 0, 0, 400, 800, this);
	}
}

class hqImagePanel extends JPanel implements ActionListener{

    public Image background;
    public Image space;
    public Image space2;
    public Image piece1;
    public Image piece2;
    public Image wall1;
    public Image wall2;

    public int p1x;
    public int p1y;
    public int p2x;
    public int p2y;
    public int player;
    public int playerNum;

	public squareWalls[][] walls = new squareWalls[9][11];

    private MouseHandler mouseHandler;
    private JTextField tf = new JTextField();
    private hardquorGameClient game;

    public hqImagePanel(Image background, Image space, Image space2, Image piece1, Image piece2, Image wall1, Image wall2, JTextField tf, hardquorGameClient game, int playerNum) {
        for(int i=0;i<9;i++) {
			for(int j=0;j<11;j++) {
				walls[i][j] = new squareWalls();
			}
		}
        this.background = background;
        this.space = space;
        this.space2 = space2;
        this.piece1 = piece1;
        this.piece2 = piece2;
        this.wall1 = wall1;
        this.wall2 = wall2;
        this.tf = tf;
        tf.addActionListener(this);
        this.game = game;
        this.playerNum = playerNum;
        mouseHandler = new MouseHandler(this, game);
        addMouseListener(mouseHandler);
        p1x = 4;
		p1y = 0;
		p2x = 4;
		p2y = 10;

        player = 1;

    }

  public void actionPerformed(ActionEvent e)
  {
	game.speak(tf.getText());
    tf.setText("");
  }

    public void paintComponent(Graphics g) {
		//paint background
        super.paintComponent(g);
        g.drawImage(background, 0, 0, 800, 800, this);

        // paint board
        for(int i=0;i<9;i++) {
        	for(int j=0;j<11;j++) {
				if(j == 0)
		        	g.drawImage(space2, 55 + i*62, 55 + j*62, this);
		        else if(j == 10)
		        	g.drawImage(space2, 55 + i*62, 55 + j*62, this);
		        else
		        	g.drawImage(space, 55 + i*62, 55 + j*62, this);
		        if(i==p1x && j==10 - p1y)
					g.drawImage(piece1, 60 + i*62, 60 + j*62, this);
				if(i==p2x && j== 10 - p2y)
					g.drawImage(piece2, 60 + i*62, 60 + j*62, this);
				if(walls[i][10 - j].getRight())
					g.drawImage(wall1, 55 + i*62, 109 + j*62, this);
				if(walls[i][10 - j].getBottom())
					g.drawImage(wall2, 109 + i*62, 55 + j*62, this);
			}
		}
    }
}

class MouseHandler extends MouseAdapter {

	private hqImagePanel p;
	private hardquorGameClient game;

	public MouseHandler (hqImagePanel panel, hardquorGameClient game) {
		p = panel;
		this.game = game;
	}

	public void mouseReleased(MouseEvent e) {
		int mouseX = e.getX();
    	int mouseY = e.getY();
    	int tmpX = 0;
    	int tmpY = 0;
    	boolean xPos = false;
    	boolean yPos = false;
    	boolean wallX = false;
    	boolean wallY = false;

		System.out.println("x:" + mouseX + " y:" + mouseY);

    	mouseX -= 55;
    	if(mouseX >= 0 && mouseX <= 550) {
    		while(!xPos) {
    			if(mouseX - 54 <= 0) {
					xPos = true;
				}
    			else if(mouseX - 62 < 0) {
					wallX = true;
					xPos = true;
				}
    			else {
					mouseX -= 62;
					tmpX++;
				}
			}

			mouseY -= 55;
			if(mouseY >= 0 && mouseY <= 674) {
				while(!yPos) {
					if(mouseY - 54 < 0) {
						yPos = true;
					}
					else if(mouseY - 62 < 0) {
						wallY = true;
						yPos = true;
					}
					else {
						mouseY -= 62;
						tmpY++;
					}
				}

                if (wallX == true && wallY == true) {
					System.out.println("Invalid Wall");
				}
                else if  (wallX || wallY) {
					System.out.println("Wall");
					if(wallX)
						game.tryMove(new int[] {tmpX, 10 - tmpY}, new int[] {tmpX, 10 - tmpY - 1}, new int[] {tmpX + 1, 10 - tmpY}, new int[] {tmpX + 1, 10 - tmpY - 1});
						//p.walls[tmpX][tmpY].setBottom();
					else
						game.tryMove(new int[] {tmpX, 10 - tmpY}, new int[] {tmpX + 1, 10 - tmpY}, new int[] {tmpX, 10 - tmpY - 1}, new int[] {tmpX + 1, 10 - tmpY - 1});
						//p.walls[tmpX][tmpY].setRight();*/
				}
				else if (p.playerNum == 0) {
					game.tryMove(new int[] {p.p1x, p.p1y}, new int[] {tmpX, 10 - tmpY});
					System.out.print("Player0");
					//p.p1x = tmpX;
					//p.p1y = tmpY;
				}
				else if (p.playerNum == 1) {
					game.tryMove(new int[] {p.p2x, p.p2y}, new int[] {tmpX, 10 - tmpY});
					System.out.print("Player1");
					//p.p2x = tmpX;
					//p.p2y = tmpY;
				}

				else {
					System.out.println("ERROR");
				}

				//p.repaint();
			}
			else {
				System.out.println("Invalid X");
			}
		}
		else {
			System.out.println("Invalid Y");
		}
   	}
}

class FileOpenListener implements ActionListener {
	JFrame f;
	JLabel fl;
	hqImagePanel p;
	public FileOpenListener(JFrame frame, hqImagePanel imagePanel, JLabel fileLabel) {
		f = frame;
		fl = fileLabel;
		p = imagePanel;
	}

	public void actionPerformed(ActionEvent e) {
    	FileDialog fd = new FileDialog(f, "Open");
    	fd.show();
    	String fileName = fd.getFile();
    	String Directory = fd.getDirectory();
    	System.out.println(fileName);
    	String dirFileName = Directory + fileName;
    	//fl.setText(" " + dirFileName);
    	fl.setText(" " + fileName.substring(0, 10) + "...");
    	if(fileName != null) {
    	  	try {
				BufferedReader in = new BufferedReader(new FileReader(dirFileName));
				p.background = Toolkit.getDefaultToolkit().getImage(in.readLine());
				p.space = Toolkit.getDefaultToolkit().getImage(in.readLine());
				p.space2 = Toolkit.getDefaultToolkit().getImage(in.readLine());
    			in.close();
			}
			catch(IOException ex) {
				ex.printStackTrace();
				System.exit(1);
    		}

    		p.repaint();
		}

   }
}

class squareWalls {
	private boolean right;
	private boolean bottom;
	public squareWalls() {
		right = false;
		bottom = false;
	}
	public void setRight() {
		right = true;
	}

	public void setBottom() {
		bottom = true;
	}

	public boolean getRight() {
		return right;
	}

	public boolean getBottom() {
		return bottom;
	}
}

class hqSimpleGUICloseHandler extends WindowAdapter
{
  public hardquorGameClient gameClient;

  public hqSimpleGUICloseHandler(hardquorGameClient gameClient)
  { this.gameClient = gameClient;
  }

  public void windowClosing(WindowEvent e)
  { gameClient.gameQuit();
  }

}
